#include<stdio.h>
#include<assert.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/wait.h>
#include<sys/types.h>

//test6 execle 
int main(int arg, char* argc[], char* env[])
{
  printf("process is running\n");
  pid_t id =fork();
  assert(id != -1);
  
  if(id == 0)
  {
    //这里的程序替换会影响父进程吗？  不会！！  因为进程具有独立性！！
    sleep(1);

    char * const envp_[]={(char*)"MYENV=1111222233334444", NULL};
    //execle("./mybin", "./mybin", NULL, envp_);  //自定义环境变量
    
    // 使用命令行参数env
    // execle("./mybin", "./mybin", NULL, env);
    
    //使用库中的environ
    extern char **environ;

    putenv((char*)"MYENV_=4444333322221111");  //将指定环境变量导入到系统中，即environ指向的表（指针数组）
    putenv(envp_[0]);
    execle("./mybin", "./mybin", NULL, environ);  // 实际上，默认环境变量，你不传入，子进程也能获取 

    exit(-1);
  }
  
  int status = 0;
  pid_t ret = waitpid(id, &status, 0);
  if(ret > 0) 
  {
    printf("wait success: exit_code:%d, exit_signal:%d\n", (status>>8) & 0xff, status & 0x7f);
  }
  
  return 0;
}

/*
// test5  执行自己的命令
int main()
{
  printf("process is running\n");
  pid_t id =fork();
  assert(id != -1);
  
  if(id == 0)
  {
    //这里的程序替换会影响父进程吗？  不会！！  因为进程具有独立性！！
    sleep(1);
    
    //执行C代码程序
    //execl("./mybin", "./mybin", NULL);
    
    //执行c++程序
    execl("./mycpp", "./mycpp", NULL);
    
    //如果失败
    exit(-1);
  }
  
  int status = 0;
  pid_t ret = waitpid(id, &status, 0);
  if(ret > 0) 
  {
    printf("wait success: exit_code:%d, exit_signal:%d\n", (status>>8) & 0xff, status & 0x7f);
  }
  
  return 0;
}
*/

/*
// test4
int main()
{
  printf("process is running\n");
  pid_t id =fork();
  assert(id != -1);
  
  if(id == 0)
  {
    //这里的程序替换会影响父进程吗？  不会！！  因为进程具有独立性！！
    sleep(1);
    
    //execv(const char* path, char* const argv[]), 第二个是指针数组
    
    char * const argv_[]={"ls", "-a", "-l", "--color=auto", NULL};

    execv("/usr/bin/ls",argv_);
   
    //execvp
    execvp("ls",argv_);

    //如果失败
    exit(-1);
  }
  
  int status = 0;
  pid_t ret = waitpid(id, &status, 0);
  if(ret > 0) 
  {
    printf("wait success: exit_code:%d, exit_signal:%d\n", (status>>8) & 0xff, status & 0x7f);
  }
  
  return 0;
}
*/
    
/*
// test3
int main()
{
  printf("process is running\n");
  pid_t id =fork();
  assert(id != -1);
  
  if(id == 0)
  {
    //这里的程序替换会影响父进程吗？  不会！！  因为进程具有独立性！！
    sleep(1);
    
    //这里有两个ls,重复吗？（第一个表示我是谁，第二个表示怎么执行）
    execlp("ls", "ls", "-a", "-l", "--color=auto", NULL);
    
    
    //如果失败
    exit(-1);
  }
  
  int status = 0;
  pid_t ret = waitpid(id, &status, 0);
  if(ret > 0) 
  {
    printf("wait success: exit_code:%d, exit_signal:%d\n", (status>>8) & 0xff, status & 0x7f);
  }
  
  return 0;
}
*/

/*
// test2
int main()
{
  printf("process is running\n");
  pid_t id =fork();
  assert(id != -1);
  
  if(id == 0)
  {
    //这里的程序替换会影响父进程吗？  不会！！  因为进程具有独立性！！
    sleep(1);
    execl("/usr/bin/ls", "ls", "-a", "-l", "--color=auto", NULL);
    //如果失败
    exit(-1);
  }
  
  int status = 0;
  pid_t ret = waitpid(id, &status, 0);
  if(ret > 0) 
  {
    printf("wait success: exit_code:%d, exit_signal:%d\n", (status>>8) & 0xff, status & 0x7f);
  }
  
  return 0;
}
*/

// test1
//int main ()
//{
//  // .c -> exe -> load -> process -> 运行 -> 执行我们写的代码
//  printf("process is running\n");
//
//  // load -> exe
//  //1.执行ls
//  execl("/usr/bin/ls"/*要执行哪一个程序，填这个程序的路径*/, "ls", "--color=auto", "-a", "-l", NULL/*命令怎么执行，这里就怎么填写*/); // all exec* end of NULL
//
//  //2.执行top 
//  //execl("/usr/bin/top"/*要执行哪一个程序，填这个程序的路径*/, "top",  NULL/*命令怎么执行，这里就怎么填写*/); // all exec* end of NULL
//
//  //3. 只要执行一个函数，就有可能执行失败，如果执行失败，就会继续向后执行代码
//  // 执行失败，返回负数。执行成功，没有返回值（因为成功了，就说明和execl后面的代码无关），所以我们只要进行错误处理
//  perror("execl");//打印执行错误
//
//
//  // 执行execl之后，代码被覆盖。printf无法执行
//  printf("process running done \n");
//  exit(1);
//  return 0;
//}
